package com.example.chapter07_client;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.example.chapter07_client.entity.Contact;

import java.util.ArrayList;

public class ContactAddActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText et_contact_name, et_contact_phone, et_contact_email;
    private static final int REQUEST_CODE_READ_CONTACTS = 100;
    private static final int REQUEST_CODE_ADD_CONTACT = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact_add);

        et_contact_name = findViewById(R.id.et_contact_name);
        et_contact_phone = findViewById(R.id.et_contact_phone);
        et_contact_email = findViewById(R.id.et_contact_email);
        findViewById(R.id.btn_add_contact).setOnClickListener(this);
        findViewById(R.id.btn_read_contact).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_add_contact) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_ADD_CONTACT);
            } else {
                addContact();
            }
        } else if (v.getId() == R.id.btn_read_contact) {
            // 读取手机通讯录
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE_READ_CONTACTS);
            } else {
                readPhoneContacts(getContentResolver());
            }
        }
    }

    @SuppressLint("Range")
    private void readPhoneContacts(ContentResolver contentResolver) {
        // 先查询 raw_contacts 表，再根据 raw_contact_id 查询 data 表
        Cursor cursor = contentResolver.query(ContactsContract.RawContacts.CONTENT_URI, new String[]{ContactsContract.RawContacts._ID}, null, null, null);
        while (cursor.moveToNext()) {
            int rawContactId = cursor.getInt(0);
            Uri uri = Uri.parse("content://com.android.contacts/contacts/" + rawContactId + "/data");
            Cursor dataCursor = contentResolver.query(uri, new String[]{ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1, ContactsContract.Data.DATA2}, null, null, null);
            Contact contact = new Contact();
            while (dataCursor.moveToNext()) {
                String data1 = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1));
                String mimeType = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
                if (mimeType.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
                    // 姓名
                    contact.name = data1;
                } else if (mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
                    // 邮箱
                    contact.email = data1;
                } else if (mimeType.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
                    // 电话
                    contact.phone = data1;
                }
            }
            dataCursor.close();

            // RawContacts 表中出现的 _id 不一定在 Data 表中都会有对应的记录
            if (contact.name != null) {
                Log.d("Mylog, ContactAddActivity", contact.toString());

            }
        }
        cursor.close();
    }

    private void addContact() {
        Contact contact = new Contact();
        contact.name = et_contact_name.getText().toString().trim();
        contact.email = et_contact_email.getText().toString().trim();
        contact.phone = et_contact_phone.getText().toString().trim();

        // 方式一，使用系统提供的ContentResolver对象，往手机通讯录添加联系人信息，多次写入，每次写入一个字段
//        addContacts(getContentResolver(), contact);
        // 方式二，批处理
        addFullContacts(getContentResolver(), contact);
    }

    // 往手机通讯录一次性添加一个联系人信息（包括姓名、电话、邮箱）
    private void addFullContacts(ContentResolver contentResolver, Contact contact) {
        // 创建一个插入联系人主记录的内容操作器
        ContentProviderOperation op_main = ContentProviderOperation
                .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                .build();
        // 创建一个插入联系人姓名记录的内容操作器
        ContentProviderOperation op_name = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.Data.DATA2, contact.name)
                .build();
        // 创建一个插入联系人电话记录的内容操作器
        ContentProviderOperation op_phone = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.Data.DATA1, contact.phone)
                .withValue(ContactsContract.Data.DATA2, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                .build();
        // 创建一个插入联系人邮箱记录的内容操作器
        ContentProviderOperation op_email = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.Data.DATA1, contact.email)
                .withValue(ContactsContract.Data.DATA2, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
                .build();
        // 声明一个内容操作器的集合，用于存放上述的内容操作器
        ArrayList<ContentProviderOperation> operations = new ArrayList<>();
        operations.add(op_main);
        operations.add(op_name);
        operations.add(op_phone);
        operations.add(op_email);
        try {
            // 批量执行内容操作器
            contentResolver.applyBatch(ContactsContract.AUTHORITY, operations);
            Log.d("Mylog, addFullContacts", "添加联系人成功");
        } catch (OperationApplicationException | RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case REQUEST_CODE_READ_CONTACTS:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    readPhoneContacts(getContentResolver());
                } else {
                    Toast.makeText(this, "权限被拒绝，无法读取联系人", Toast.LENGTH_SHORT).show();
                }
                break;

            case REQUEST_CODE_ADD_CONTACT:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    addContact();
                } else {
                    Toast.makeText(this, "需要权限才能添加联系人", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    // 往手机通讯录添加一个联系人信息（包括姓名、电话、邮箱）
    private void addContacts(ContentResolver contentResolver, Contact contact) {
        ContentValues contentValues = new ContentValues();
        // 向RawContacts.CONTENT_URI执行一个空值插入，目的是获取系统返回的rawContactId
        Uri uri = contentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, contentValues);
        long rawContactId = ContentUris.parseId(uri);

        ContentValues name = new ContentValues();
        // 关联联系人编号
        name.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
        // “姓名”的数据类型
        name.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        // 联系人的姓名
        name.put(ContactsContract.RawContacts.Data.DATA2, contact.name);
        // 往提供器添加联系人姓名信息
        contentResolver.insert(ContactsContract.Data.CONTENT_URI, name);

        ContentValues phone = new ContentValues();
        phone.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
        phone.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        // 联系人的电话号码，联系类型：1表示家庭，2表示工作
        phone.put(ContactsContract.RawContacts.Data.DATA1, contact.phone);
        phone.put(ContactsContract.RawContacts.Data.DATA2, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        contentResolver.insert(ContactsContract.Data.CONTENT_URI, phone);

        ContentValues email = new ContentValues();
        email.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
        email.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
        email.put(ContactsContract.RawContacts.Data.DATA1, contact.email);
        email.put(ContactsContract.RawContacts.Data.DATA2, ContactsContract.CommonDataKinds.Email.TYPE_MOBILE);
        contentResolver.insert(ContactsContract.Data.CONTENT_URI, email);
    }
}